Erros comuns de tipagem em projetos Django e como corrigi-los
#public
Essa documentação tem como objetivo ajudar a corrigir erros de tipagem apontados pelo pyright em projetos Django.
Aqui você encontra exemplos de como corrigir alguns problemas comuns. Leia também a documentação do django-types para saber mais.
Usar propriedades de objetos Lazy
Algumas instâncias de classes que herdam de django.utils.functional.Lazy
podem apresentar erros de tipagem, exemplo:
Cannot access member "url" for type "PublicMediaStorage"
Member "url" is unknown
Para corrigir altere o lugar onde é instanciado o objeto lazy para definir o tipo concreto dele, exemplo:
-public_media_storage: Storage = PublicMediaStorage()
+public_media_storage: Storage = cast(Storage, PublicMediaStorage())
Acessar ID de uma ForeignKey
Por padrão o pyright não conhece os campos _id
das ForeignKeys. Então você tiver um model com uma ForeignKey, por exemplo para User.
class Profile(models.Model):
user = models.ForeignKey('auth.User')
E tentar fazer:
def example(profile: Profile):
profile.user_id
Você vai receber o erro:
Cannot access member "user_id" for type "Profile"
Member "user_id" is unknown
Para que o pyright conheça o campo user_id
adicione ele no modelo.
class Profile(models.Model):
+ user_id: int
user = models.ForeignKey('auth.User')
Acessar id
de modelos
O pyright não conhece o campos id
dos modelos. A seguinte mensagem de erro aparece quando você tem acessa o id de um model.
Cannot access member "id" for type "Profile"
Member "id" is unknown
Para corrigir use o atributo pk
presente nos models, exemplo:
def example(profile: Profile):
profile.pk
Ou, para corrigir códigos legados, adiciona a anotação de tipo id: int
na definição do modelo.
class Profile(models.Model):
+ id: int
Acessar propriedade de modelo que pode ser nula
Se um campo de modelo for definido como null=True, como abaixo:
class Profile(models.Model):
birth_date = models.DateField(null=True)
Ao tentar usar ele como abaixo:
def example(profile: Profile):
profile.birth_date.strftime('%d/%m/%Y')
Você pode receber o erro: “strftime” is not a known member of “None”
Para resolver isso você pode:
(1) Adicionar uma verificação que garante que ao acessar o campo ele não seja nulo.
def example(profile: Profile):
if profile.birth_date is None:
profile.birth_date.strftime('%d/%m/%Y')
# OU lançar uma exception
if profile.birth_date is None:
raise ValueError('...')
(2) Caso o modelo realmente não possa receber valores nulo nesse campo, fazer uma migração para garantir isso a nível de banco de dados.
- birth_date = models.DateField(null=True, blank=True)
+ birth_date = models.DateField(null=False, blank=True)
[!danger] Migrações são perigosas Tenha em mente que a migração pode ser lenta para tabelas grandes e pode causar lock no banco de dados. Não faça a migração se não tiver segurança do que vai acontecer.